package com.hxgis.common.service.impl;

import com.es.common.EsAggCondition;
import com.es.common.domain.EsCondition;
import com.es.common.domain.agg.Group;
import com.es.common.enums.FlagConnect;
import com.es.common.enums.Order;
import com.es.wrapper.DataWrapper;
import com.hxgis.common.base.ResultVO;
import com.hxgis.common.dto.ExtremeAnaStationDTO;
import com.hxgis.common.dto.ExtremeYearDataDTO;
import com.hxgis.common.dto.RainInfoAnalysDTO;
import com.hxgis.common.entity.RainDayInfo;
import com.hxgis.common.entity.RainExtremeInfo;
import com.hxgis.common.entity.Station;
import com.hxgis.common.entity.StationExtremeInfo;
import com.hxgis.common.enums.RainFlagEnum;
import com.hxgis.common.repository.RainDayInfoRepository;
import com.hxgis.common.repository.RainExtremeInfoRepository;
import com.hxgis.common.repository.StationInfoRepository;
import com.hxgis.common.service.RainDayService;
import com.hxgis.common.service.RainExtremeInfoService;
import com.hxgis.common.service.StationExtremeService;
import com.hxgis.common.service.StationService;
import com.hxgis.common.utils.NumUtil;
import com.hxgis.common.utils.RectField;
import com.hxgis.common.utils.ResultVOUtil;
import com.hxgis.common.utils.TimeUtil;
import com.hxgis.common.vo.ExtremeAnalysisVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 极端信息service
 */
@Slf4j
@Service
public class RainExtremeInfoServiceImpl implements RainExtremeInfoService {

    @Autowired
    private RainExtremeInfoRepository extremeInfoRepository;

    @Autowired
    private RainDayInfoRepository rainDayInfoRepository;

    @Autowired
    private StationExtremeService stationExtremeService;

    @Autowired
    private StationService stationService;

    @Autowired
    private StationInfoRepository stationInfoRepository;

    @Autowired
    RainDayService rainDayService;

    /**
     * 将降水数据跑至极端数据 连续1-15天
     * @param startTime
     * @param endTime
     */
    @Override
    public void saveExtremeInfo(String startTime, String endTime, List<StationExtremeInfo> stationExtremeInfos) {
        Map<String, List<StationExtremeInfo>> extremeInfoMaps = stationExtremeInfos.stream().collect(Collectors.groupingBy(StationExtremeInfo::getStationNo));

        EsCondition esCondition = EsCondition.getEsCondition();
        esCondition.gte("time",startTime).lte(endTime);
        esCondition.size(1000000);
        List<RainDayInfo> rainDayInfos = rainDayInfoRepository.selectList(esCondition);


        Map<String, List<RainDayInfo>> rainDaysMap = rainDayInfos.stream().collect(Collectors.groupingBy(RainDayInfo::getStationNo));
        List<RainExtremeInfo> extremeInfoList = new ArrayList<>();
        rainDaysMap.forEach((stationNo, rainDayInfoList) -> {
            //循环这批数据处理
            rainDayInfoList.stream().forEach(raindayInfo->{
                if (!CollectionUtils.isEmpty(extremeInfoMaps.get(raindayInfo.getStationNo()))){
                    RainExtremeInfo rainExtremeInfo = new RainExtremeInfo();
                    //定义一个flag 30个进行flag &
                    if (Objects.nonNull(raindayInfo.getRainFall()) && raindayInfo.getRainFall() < 50000 && raindayInfo.getRainFall().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_1()) >= 0){
                        rainExtremeInfo.setRainFall(raindayInfo.getRainFall());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_2()) && raindayInfo.getRainFall_2().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_2()) >= 0){
                        rainExtremeInfo.setRainFall_2(raindayInfo.getRainFall_2());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_3()) && raindayInfo.getRainFall_3().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_3()) >= 0){
                        rainExtremeInfo.setRainFall_3(raindayInfo.getRainFall_3());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_4()) && raindayInfo.getRainFall_4().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_4()) >= 0){
                        rainExtremeInfo.setRainFall_4(raindayInfo.getRainFall_4());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_5()) && raindayInfo.getRainFall_5().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_5()) >= 0){
                        rainExtremeInfo.setRainFall_5(raindayInfo.getRainFall_5());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_6()) && raindayInfo.getRainFall_6().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_6()) >= 0){
                        rainExtremeInfo.setRainFall_6(raindayInfo.getRainFall_6());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_7()) && raindayInfo.getRainFall_7().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_7()) >= 0){
                        rainExtremeInfo.setRainFall_7(raindayInfo.getRainFall_7());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_8()) && raindayInfo.getRainFall_8().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_8()) >= 0){
                        rainExtremeInfo.setRainFall_8(raindayInfo.getRainFall_8());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_9()) && raindayInfo.getRainFall_9().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_9()) >= 0){
                        rainExtremeInfo.setRainFall_9(raindayInfo.getRainFall_9());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_10()) && raindayInfo.getRainFall_10().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_10()) >= 0){
                        rainExtremeInfo.setRainFall_10(raindayInfo.getRainFall_10());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_11()) && raindayInfo.getRainFall_11().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_11()) >= 0){
                        rainExtremeInfo.setRainFall_11(raindayInfo.getRainFall_11());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_12()) && raindayInfo.getRainFall_12().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_12()) >= 0){
                        rainExtremeInfo.setRainFall_12(raindayInfo.getRainFall_12());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_13()) && raindayInfo.getRainFall_13().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_13()) >= 0){
                        rainExtremeInfo.setRainFall_13(raindayInfo.getRainFall_13());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_14()) && raindayInfo.getRainFall_14().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_14()) >= 0){
                        rainExtremeInfo.setRainFall_14(raindayInfo.getRainFall_14());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall_15()) && raindayInfo.getRainFall_15().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold20_15()) >= 0){
                        rainExtremeInfo.setRainFall_15(raindayInfo.getRainFall_15());
                    }
                    //08
                    if (Objects.nonNull(raindayInfo.getRainFall08()) && raindayInfo.getRainFall08() < 50000 && raindayInfo.getRainFall08().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_1()) >= 0){
                        rainExtremeInfo.setRainFall08(raindayInfo.getRainFall08());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_2()) && raindayInfo.getRainFall08_2().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_2()) >= 0){
                        rainExtremeInfo.setRainFall08_2(raindayInfo.getRainFall08_2());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_3()) && raindayInfo.getRainFall08_3().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_3()) >= 0){
                        rainExtremeInfo.setRainFall08_3(raindayInfo.getRainFall08_3());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_4()) && raindayInfo.getRainFall08_4().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_4()) >= 0){
                        rainExtremeInfo.setRainFall08_4(raindayInfo.getRainFall08_4());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_5()) && raindayInfo.getRainFall08_5().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_5()) >= 0){
                        rainExtremeInfo.setRainFall08_5(raindayInfo.getRainFall08_5());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_6()) && raindayInfo.getRainFall08_6().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_6()) >= 0){
                        rainExtremeInfo.setRainFall08_6(raindayInfo.getRainFall08_6());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_7()) && raindayInfo.getRainFall08_7().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_7()) >= 0){
                        rainExtremeInfo.setRainFall08_7(raindayInfo.getRainFall08_7());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_8()) && raindayInfo.getRainFall08_8().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_8()) >= 0){
                        rainExtremeInfo.setRainFall08_8(raindayInfo.getRainFall08_8());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_9()) && raindayInfo.getRainFall08_9().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_9()) >= 0){
                        rainExtremeInfo.setRainFall08_9(raindayInfo.getRainFall08_9());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_10()) && raindayInfo.getRainFall08_10().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_10()) >= 0){
                        rainExtremeInfo.setRainFall08_10(raindayInfo.getRainFall08_10());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_11()) && raindayInfo.getRainFall08_11().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_11()) >= 0){
                        rainExtremeInfo.setRainFall08_11(raindayInfo.getRainFall08_11());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_12()) && raindayInfo.getRainFall08_12().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_12()) >= 0){
                        rainExtremeInfo.setRainFall08_12(raindayInfo.getRainFall08_12());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_13()) && raindayInfo.getRainFall08_13().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_13()) >= 0){
                        rainExtremeInfo.setRainFall08_13(raindayInfo.getRainFall08_13());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_14()) && raindayInfo.getRainFall08_14().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_14()) >= 0){
                        rainExtremeInfo.setRainFall08_14(raindayInfo.getRainFall08_14());
                    }
                    if (Objects.nonNull(raindayInfo.getRainFall08_15()) && raindayInfo.getRainFall08_15().compareTo(extremeInfoMaps.get(raindayInfo.getStationNo()).get(0).getRainThreshold08_15()) >= 0){
                        rainExtremeInfo.setRainFall08_15(raindayInfo.getRainFall08_15());
                    }

                    // 判断赋值过没
                    if (isNotNull(rainExtremeInfo)){
                        rainExtremeInfo.setId(raindayInfo.getId());
                        rainExtremeInfo.setTime(raindayInfo.getTime().intValue());
                        rainExtremeInfo.setYear(raindayInfo.getYear());
                        rainExtremeInfo.setStationNo(raindayInfo.getStationNo());
                        rainExtremeInfo.setDays(raindayInfo.getDays());
                        extremeInfoList.add(rainExtremeInfo);
                    }
                }
            });
        });
        extremeInfoRepository.saveBatch(extremeInfoList);
        log.info("{}到{}的极端事件保存完成",startTime,endTime);
    }



    private boolean isNotNull(RainExtremeInfo rainExtremeInfo){

        return  Objects.nonNull(rainExtremeInfo.getRainFall()) || Objects.nonNull(rainExtremeInfo.getRainFall_2()) || Objects.nonNull(rainExtremeInfo.getRainFall_3()) || Objects.nonNull(rainExtremeInfo.getRainFall_4()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall_5()) || Objects.nonNull(rainExtremeInfo.getRainFall_6()) || Objects.nonNull(rainExtremeInfo.getRainFall_7()) || Objects.nonNull(rainExtremeInfo.getRainFall_8()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall_9()) || Objects.nonNull(rainExtremeInfo.getRainFall_10()) || Objects.nonNull(rainExtremeInfo.getRainFall_11()) || Objects.nonNull(rainExtremeInfo.getRainFall_12()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall_13()) || Objects.nonNull(rainExtremeInfo.getRainFall_14()) || Objects.nonNull(rainExtremeInfo.getRainFall_15()) || Objects.nonNull(rainExtremeInfo.getRainFall08()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall08_2()) || Objects.nonNull(rainExtremeInfo.getRainFall08_3()) || Objects.nonNull(rainExtremeInfo.getRainFall08_4()) || Objects.nonNull(rainExtremeInfo.getRainFall08_5()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall08_9()) || Objects.nonNull(rainExtremeInfo.getRainFall08_11()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall08_6()) || Objects.nonNull(rainExtremeInfo.getRainFall08_7()) || Objects.nonNull(rainExtremeInfo.getRainFall08_8()) || Objects.nonNull(rainExtremeInfo.getRainFall08_10()) ||
                Objects.nonNull(rainExtremeInfo.getRainFall08_12()) || Objects.nonNull(rainExtremeInfo.getRainFall08_13()) || Objects.nonNull(rainExtremeInfo.getRainFall08_14()) || Objects.nonNull(rainExtremeInfo.getRainFall08_15());
    }

    @Override
    public void saveExtremeInfoByYear(String startYear, String endYear, List<StationExtremeInfo> stationExtremeInfos) {

    }

    /**
     * 极端事件 极端日降水量
     * @param startTime
     * @param endTime
     * @param flag
     * @param continueDay
     */
    @Override
    public ResultVO queryRailSum(String startTime, String endTime, String leftTime, String rightTime, String flag, Integer continueDay, String stationNum, String riverName) {
        Long st = System.currentTimeMillis();
        //查询区域内的站点
        EsCondition stationCondition = EsCondition.getEsCondition();
        if (Objects.nonNull(riverName)){
            stationCondition.eq("river",riverName);
        }
        List<Station> stationList = stationInfoRepository.selectList(stationCondition);
        List<String> stationNoList = RectField.getBeanFields(stationList, "stationNo");

        //todo 站点的最大值相关信息开始
        EsAggCondition esAggCondition = EsAggCondition.getInstance();
        Group stationNoGroup = esAggCondition.Group("stationNo");
        stationNoGroup.size(10000);
        Group yearGroup = stationNoGroup.groupSub("time");
        if (Objects.equals(continueDay,1)){
            yearGroup.sum(RainFlagEnum.getRainFlagEnum(flag).getMessage(),"rainFallSum");
        }else{
            yearGroup.sum(RainFlagEnum.getRainFlagEnum(flag).getMessage()+"_"+continueDay,"rainFallSum");
        }
        yearGroup.order(Order.DESC,"rainFallSum");
        yearGroup.size(1);
        EsCondition condition = esAggCondition.getCondition();
        condition.in("stationNo", com.hxgis.common.utils.CollectionUtils.convertCollectionString(stationNoList));
        condition.gte("time",leftTime).lte(rightTime)
                .lte(RainFlagEnum.getRainFlagEnum(flag).getMessage(),20000);
        List<RainInfoAnalysDTO> rainInfoAnalysDTOS = rainDayInfoRepository.selectListAgg(esAggCondition, new DataWrapper<RainInfoAnalysDTO>() {
            @Override
            public RainInfoAnalysDTO wrapper(Map<String, Object> data) {
                RainInfoAnalysDTO rainInfoAnalysDTO = new RainInfoAnalysDTO();
                rainInfoAnalysDTO.setStationNo(data.get("stationNo").toString());
                rainInfoAnalysDTO.setTime(data.get("time").toString());
                rainInfoAnalysDTO.setRainFallSum(Double.parseDouble(data.get("rainFallSum").toString())/10);
                return rainInfoAnalysDTO;
            }
        });
        Map<String, List<RainInfoAnalysDTO>> rainFallMaxMaps = rainInfoAnalysDTOS.stream().collect(Collectors.groupingBy(RainInfoAnalysDTO::getStationNo));
        //todo 站点的最大值相关信息结束

        //todo 站点阈值信息
        List<StationExtremeInfo> allExtreInfo = stationExtremeService.getAllExtreInfo();
        Map<String, List<StationExtremeInfo>> extremeInfoMaps = allExtreInfo.stream().collect(Collectors.groupingBy(StationExtremeInfo::getStationNo));

        //todo 查询大于阈值的相关数据信息

        EsAggCondition extremeAggCondition = EsAggCondition.getInstance();
        Group extremeStationGroup = extremeAggCondition.Group("stationNo");
        extremeStationGroup.size(10000);
        Group extremeYearGroup = extremeStationGroup.groupSub("time");
        if (Objects.equals(continueDay,1)){
            extremeYearGroup.sum(RainFlagEnum.getRainFlagEnum(flag).getMessage(),"rainFallSum");
        }else{
            extremeYearGroup.sum(RainFlagEnum.getRainFlagEnum(flag).getMessage()+"_"+continueDay,"rainFallSum");
        }
        extremeYearGroup.order(Order.DESC,"rainFallSum");
        extremeYearGroup.size(100);
        EsCondition extremeCondition = extremeAggCondition.getCondition();
        extremeCondition.in("stationNo", com.hxgis.common.utils.CollectionUtils.convertCollectionString(stationNoList));

//                .lte(RainFlagEnum.getRainFlagEnum(flag).getMessage(),20000);
        if (Objects.equals(continueDay,1)){
            extremeCondition.eq(RainFlagEnum.getRainFlagEnum(flag).getMessage(),null).not();
        }else{
            extremeCondition.eq(RainFlagEnum.getRainFlagEnum(flag).getMessage()+"_"+continueDay,null).not();
        }



        if (Objects.equals(startTime.substring(0,4),endTime.substring(0,4))){
            extremeCondition.gte("time",leftTime).lte(rightTime)
                    .gte("days", startTime.substring(4,8)).lte(endTime.substring(4,8));
        }else{
            extremeCondition.gte("time",leftTime).lte(rightTime);
//                    .gte("days", startTime.substring(4,8)).lte(endTime.substring(4,8));
            EsCondition ed = EsCondition.getEsCondition().gte("days", startTime.substring(4, 8)).lte("1231")
                    .or().gte("days", "0101").lte(endTime.substring(4, 8)).or();

            extremeCondition.subSearch(ed, FlagConnect.AND);
        }

        if (Objects.nonNull(stationNum)){
            extremeCondition.eq("stationNo",stationNum);
        }

        List<RainInfoAnalysDTO> extremeRainInfos = extremeInfoRepository.selectListAgg(extremeAggCondition, new DataWrapper<RainInfoAnalysDTO>() {
            @Override
            public RainInfoAnalysDTO wrapper(Map<String, Object> data) {
                RainInfoAnalysDTO rainInfoAnalysDTO = new RainInfoAnalysDTO();
                rainInfoAnalysDTO.setTime(data.get("time").toString());
                rainInfoAnalysDTO.setStationNo(data.get("stationNo").toString());
                rainInfoAnalysDTO.setRainFallSum(Double.parseDouble(data.get("rainFallSum").toString())/10);
                return rainInfoAnalysDTO;
            }
        });
        Map<String, List<RainInfoAnalysDTO>> stationExtremeInfoMaps = extremeRainInfos.stream().collect(Collectors.groupingBy(RainInfoAnalysDTO::getStationNo));

        log.info("极端事件 极端日降水查询es用时{}",System.currentTimeMillis() - st );
        //todo 站点相关信息
        Map<String, Station> stringStationMap = stationService.queryAllStation();
        List<ExtremeAnaStationDTO> extremeAnaStationDTOS = new ArrayList<>();
        if (Objects.nonNull(stationNum)){
            if (CollectionUtils.isEmpty(stationExtremeInfoMaps)){
                ExtremeAnaStationDTO extremeAnaStationDTO = new ExtremeAnaStationDTO();
                extremeAnaStationDTO.setStationNo(stationNum);
                extremeAnaStationDTO.setStationName(stringStationMap.get(stationNum).getCity());
                extremeAnaStationDTO.setProvince(stringStationMap.get(stationNum).getProvince());
                extremeAnaStationDTO.setRiver(stringStationMap.get(stationNum).getRiver());
                extremeAnaStationDTO.setRegion(stringStationMap.get(stationNum).getRegion());
                extremeAnaStationDTO.setLat((Double.valueOf(stringStationMap.get(stationNum).getLat())));
                extremeAnaStationDTO.setLon((Double.valueOf(stringStationMap.get(stationNum).getLon())));
                extremeAnaStationDTO.setYear("999999");
                extremeAnaStationDTO.setObserDate("999999");
                extremeAnaStationDTO.setPreObserDate("999999");
                extremeAnaStationDTO.setValue(999999d);
                //查看阈值
                Double extremeValue = getExtremeValue(stationNum, continueDay, flag, extremeInfoMaps);
                extremeAnaStationDTO.setExtremeValue(extremeValue);
                Double rainFallSum = Double.valueOf(rainFallMaxMaps.get(stationNum).get(0).getRainFallSum());
                extremeAnaStationDTO.setMaxValue(rainFallSum);
                extremeAnaStationDTO.setMaxObserDate(rainFallMaxMaps.get(stationNum).get(0).getTime());
                extremeAnaStationDTO.setIsExtreme(false);
                extremeAnaStationDTO.setIsMaxValue(false);
                extremeAnaStationDTOS.add(extremeAnaStationDTO);
                return ResultVOUtil.success(extremeAnaStationDTOS);
            }
            stationExtremeInfoMaps.forEach((stationNo,rainInfoAnalysDTOList) -> {
                rainInfoAnalysDTOList.stream().forEach(x -> {
                    ExtremeAnaStationDTO extremeAnaStationDTO = new ExtremeAnaStationDTO();
                    extremeAnaStationDTO.setStationNo(stationNo);
                    extremeAnaStationDTO.setProvince(stringStationMap.get(stationNo).getProvince());
                    extremeAnaStationDTO.setRiver(stringStationMap.get(stationNo).getRiver());
                    extremeAnaStationDTO.setRegion(stringStationMap.get(stationNo).getRegion());
                    extremeAnaStationDTO.setLat((Double.valueOf(stringStationMap.get(stationNo).getLat())));
                    extremeAnaStationDTO.setLon((Double.valueOf(stringStationMap.get(stationNo).getLon())));
                    extremeAnaStationDTO.setStationName(stringStationMap.get(stationNo).getCity());
                    extremeAnaStationDTO.setYear(x.getTime().substring(0,4));
                    extremeAnaStationDTO.setObserDate(x.getTime());
                    extremeAnaStationDTO.setPreObserDate(x.getTime());
                    Double nowVlaue = Double.valueOf(x.getRainFallSum());
                    extremeAnaStationDTO.setValue(nowVlaue);
                    //查看阈值
                    Double extremeValue = getExtremeValue(stationNo, continueDay, flag, extremeInfoMaps);
                    extremeAnaStationDTO.setExtremeValue(extremeValue);
                    Double rainFallSum = Double.valueOf(rainFallMaxMaps.get(stationNo).get(0).getRainFallSum());
                    extremeAnaStationDTO.setMaxValue(rainFallSum);
                    extremeAnaStationDTO.setMaxObserDate(rainFallMaxMaps.get(stationNo).get(0).getTime());
                    extremeAnaStationDTO.setIsExtreme(nowVlaue.compareTo(extremeValue) >= 0);
                    extremeAnaStationDTO.setIsMaxValue(nowVlaue.compareTo(rainFallSum) >= 0);
                    extremeAnaStationDTOS.add(extremeAnaStationDTO);
                });
            });
            log.info("极端事件 极端日降水接口总用时{}",System.currentTimeMillis() - st );
            return ResultVOUtil.success(extremeAnaStationDTOS);
        }

        //todo 表格数据 stationExtremeInfoMaps循环这个封装就行

        stationExtremeInfoMaps.forEach((stationNo,rainInfoAnalysDTOList) -> {
            //循环 rainInfoAnalysDTOList
            rainInfoAnalysDTOList.stream().forEach(x -> {
                ExtremeAnaStationDTO extremeAnaStationDTO = new ExtremeAnaStationDTO();
                extremeAnaStationDTO.setStationNo(stationNo);
                extremeAnaStationDTO.setStationName(stringStationMap.get(stationNo).getCity());
                extremeAnaStationDTO.setProvince(stringStationMap.get(stationNo).getProvince());
                extremeAnaStationDTO.setRiver(stringStationMap.get(stationNo).getRiver());
                extremeAnaStationDTO.setRegion(stringStationMap.get(stationNo).getRegion());
                extremeAnaStationDTO.setLat((Double.valueOf(stringStationMap.get(stationNo).getLat())));
                extremeAnaStationDTO.setLon((Double.valueOf(stringStationMap.get(stationNo).getLon())));
                extremeAnaStationDTO.setYear(x.getTime().substring(0,4));
                extremeAnaStationDTO.setObserDate(x.getTime());
                extremeAnaStationDTO.setPreObserDate(TimeUtil.preDay(x.getTime(),continueDay-1));
                Double nowVlaue = Double.valueOf(x.getRainFallSum());
                extremeAnaStationDTO.setValue(nowVlaue);
                //查看阈值
                Double extremeValue = getExtremeValue(stationNo, continueDay, flag, extremeInfoMaps);
                extremeAnaStationDTO.setExtremeValue(extremeValue);
                Double rainFallSum = Double.valueOf(rainFallMaxMaps.get(stationNo).get(0).getRainFallSum());
                extremeAnaStationDTO.setMaxValue(rainFallSum);
                extremeAnaStationDTO.setMaxObserDate(rainFallMaxMaps.get(stationNo).get(0).getTime());
                extremeAnaStationDTO.setIsExtreme(nowVlaue.compareTo(extremeValue) >= 0);
                extremeAnaStationDTO.setIsMaxValue(nowVlaue.compareTo(rainFallSum) >= 0);
                extremeAnaStationDTOS.add(extremeAnaStationDTO);
            });
        });



        ExtremeAnalysisVO extremeAnalysisVO = new ExtremeAnalysisVO();
        //处理表格数据 按照年分组 extremeInfoYearMaps
        Map<String, List<ExtremeAnaStationDTO>> extremeInfoYearMaps = extremeAnaStationDTOS.stream().collect(Collectors.groupingBy(ExtremeAnaStationDTO::getYear));

        //todo 查询每一年有多少有效站点
        Map<String, Integer> stringIntegerMap = rainDayService.queryYearValidStNum(riverName);


        //循环所有年份
        List<ExtremeYearDataDTO> extremeYearDataDTOS = new ArrayList<>();
        for (int i = Integer.parseInt(leftTime.substring(0, 4)); i <= Integer.parseInt(rightTime.substring(0, 4)); i++) {
            ExtremeYearDataDTO extremeYearDataDTO = new ExtremeYearDataDTO();
            List<ExtremeAnaStationDTO> extremeAnaStationDTOS1 = extremeInfoYearMaps.get(String.valueOf(i));
            //当年有效站数
            Integer validStNum = stringIntegerMap.get(String.valueOf(i));
            if (!CollectionUtils.isEmpty(extremeAnaStationDTOS1)){
                //   //极端站次
                int extremeCount = extremeAnaStationDTOS1.size();
                //    //极端站数
                Set<String> stationNos = extremeAnaStationDTOS1.stream().map(ExtremeAnaStationDTO::getStationNo).collect(Collectors.toSet());
                int extremeNum = stationNos.size();
                //    //站次比
                Double rate = new Double(0d);
                if (!Objects.equals(validStNum,0)){
                    rate = Double.valueOf(new BigDecimal(extremeCount).divide(new BigDecimal(stringIntegerMap.get(String.valueOf(i))), 4, BigDecimal.ROUND_HALF_UP).doubleValue());
                }
                extremeYearDataDTO.setExtremeCount(extremeCount).setYear(String.valueOf(i)).setExtremeNum(extremeNum).setRate(NumUtil.save2Point(rate * 100));
            }else{
                extremeYearDataDTO.setExtremeCount(0).setYear(String.valueOf(i)).setExtremeNum(0).setRate(0d);
            }
            extremeYearDataDTO.setTotalStations(validStNum);
            extremeYearDataDTOS.add(extremeYearDataDTO);

        }

        //左侧地图数据信息 循环所有站点信息
        List<ExtremeAnaStationDTO> extremeAnaStationMapDTOS = new ArrayList<>();
        Map<String, List<ExtremeAnaStationDTO>> extremeInfoStationMaps = extremeAnaStationDTOS.stream().collect(Collectors.groupingBy(ExtremeAnaStationDTO::getStationNo));
        List<Station> stations = stationService.selectAll();
        stationList.stream().forEach(station -> {
            List<ExtremeAnaStationDTO> anaStationDTOS = extremeInfoStationMaps.get(station.getStationNo());
            if (CollectionUtils.isEmpty(anaStationDTOS)){
                ExtremeAnaStationDTO extremeAnaStationDTO = getExtremeAnaStationDTO(flag, continueDay, rainFallMaxMaps, extremeInfoMaps, stringStationMap, station);
                extremeAnaStationMapDTOS.add(extremeAnaStationDTO);
            }else{
                //再将数据按照年分组查询当前年
                Map<String, List<ExtremeAnaStationDTO>> yearExtreMaps = anaStationDTOS.stream().collect(Collectors.groupingBy(ExtremeAnaStationDTO::getYear));
                //当前年信息
                List<ExtremeAnaStationDTO> extremeAnaStationDTOS1 = yearExtreMaps.get(startTime.substring(0, 4));
                if (CollectionUtils.isEmpty(extremeAnaStationDTOS1)){
                    ExtremeAnaStationDTO extremeAnaStationDTO = getExtremeAnaStationDTO(flag, continueDay, rainFallMaxMaps, extremeInfoMaps, stringStationMap, station);
                    extremeAnaStationMapDTOS.add(extremeAnaStationDTO);
                }else{
                    ExtremeAnaStationDTO extremeAnaStationDTO = new ExtremeAnaStationDTO();
                    extremeAnaStationDTO.setStationNo(station.getStationNo());
                    extremeAnaStationDTO.setStationName(stringStationMap.get(station.getStationNo()).getCity());
                    extremeAnaStationDTO.setProvince(stringStationMap.get(station.getStationNo()).getProvince());
                    extremeAnaStationDTO.setRiver(stringStationMap.get(station.getStationNo()).getRiver());
                    extremeAnaStationDTO.setRegion(stringStationMap.get(station.getStationNo()).getRegion());
                    extremeAnaStationDTO.setLat((Double.valueOf(stringStationMap.get(station.getStationNo()).getLat())));
                    extremeAnaStationDTO.setLon((Double.valueOf(stringStationMap.get(station.getStationNo()).getLon())));
                    extremeAnaStationDTO.setYear(startTime.substring(0,4));
                    extremeAnaStationDTO.setObserDate(extremeAnaStationDTOS1.get(0).getObserDate());
                    extremeAnaStationDTO.setPreObserDate(extremeAnaStationDTOS1.get(0).getObserDate());
                    Double nowVlaue = extremeAnaStationDTOS1.get(0).getValue();
                    extremeAnaStationDTO.setValue(nowVlaue);
                    //查看阈值
                    Double extremeValue = extremeAnaStationDTOS1.get(0).getExtremeValue();
                    extremeAnaStationDTO.setExtremeValue(extremeValue);
                    extremeAnaStationDTO.setMaxValue(extremeAnaStationDTOS1.get(0).getMaxValue());
                    extremeAnaStationDTO.setMaxObserDate(extremeAnaStationDTOS1.get(0).getMaxObserDate());
                    extremeAnaStationDTO.setIsExtreme(extremeAnaStationDTOS1.get(0).getIsExtreme());
                    extremeAnaStationDTO.setIsMaxValue(extremeAnaStationDTOS1.get(0).getIsMaxValue());
                    extremeAnaStationMapDTOS.add(extremeAnaStationDTO);
                }

            }
        });

        extremeAnalysisVO.setExtremeAnaStationMapDTO(extremeAnaStationMapDTOS);
        extremeAnalysisVO.setExtremeAnaStationDTOList(extremeAnaStationDTOS);
        extremeAnalysisVO.setExtremeYearDataDTOS(extremeYearDataDTOS);

        log.info("极端事件 极端日降水接口总用时{}",System.currentTimeMillis() - st );
        // 循环所有的站点信息封装数据返回结果集
        return ResultVOUtil.success(extremeAnalysisVO);

    }

    private ExtremeAnaStationDTO getExtremeAnaStationDTO(String flag, Integer continueDay, Map<String, List<RainInfoAnalysDTO>> rainFallMaxMaps, Map<String, List<StationExtremeInfo>> extremeInfoMaps, Map<String, Station> stringStationMap, Station station) {
        ExtremeAnaStationDTO extremeAnaStationDTO = new ExtremeAnaStationDTO();
        extremeAnaStationDTO.setStationNo(station.getStationNo());
        extremeAnaStationDTO.setStationName(stringStationMap.get(station.getStationNo()).getCity());
        extremeAnaStationDTO.setProvince(stringStationMap.get(station.getStationNo()).getProvince());
        extremeAnaStationDTO.setRiver(stringStationMap.get(station.getStationNo()).getRiver());
        extremeAnaStationDTO.setRegion(stringStationMap.get(station.getStationNo()).getRegion());
        extremeAnaStationDTO.setLat((Double.valueOf(stringStationMap.get(station.getStationNo()).getLat())));
        extremeAnaStationDTO.setLon((Double.valueOf(stringStationMap.get(station.getStationNo()).getLon())));
        extremeAnaStationDTO.setYear("999999");
        extremeAnaStationDTO.setObserDate("999999");
        extremeAnaStationDTO.setPreObserDate("999999");
        extremeAnaStationDTO.setValue(999999d);
        //查看阈值
        Double extremeValue = getExtremeValue(station.getStationNo(), continueDay, flag, extremeInfoMaps);
        extremeAnaStationDTO.setExtremeValue(extremeValue);
        List<RainInfoAnalysDTO> rainInfoAnalysDTOS = rainFallMaxMaps.get(station.getStationNo());
        Double rainFallSum = CollectionUtils.isEmpty(rainInfoAnalysDTOS) ? 999999d : Double.valueOf(rainFallMaxMaps.get(station.getStationNo()).get(0).getRainFallSum());
        extremeAnaStationDTO.setMaxValue(rainFallSum);
        extremeAnaStationDTO.setMaxObserDate(CollectionUtils.isEmpty(rainInfoAnalysDTOS) ? null : rainFallMaxMaps.get(station.getStationNo()).get(0).getTime());
        extremeAnaStationDTO.setIsExtreme(false);
        extremeAnaStationDTO.setIsMaxValue(false);
        return extremeAnaStationDTO;
    }


    private Double getExtremeValue(String stationNo, Integer continueDay, String flag, Map<String, List<StationExtremeInfo>> extremeInfoMaps ){
        if (CollectionUtils.isEmpty(extremeInfoMaps.get(stationNo))){
            return new Double(999999d);
        }
        if (Objects.equals(flag,"20")){
            if (Objects.equals(continueDay,1)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_1()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_1())) / 10);
            }
            if (Objects.equals(continueDay,2)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_2()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_2())) / 10);
            }
            if (Objects.equals(continueDay,3)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_3()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_3())) / 10);
            }
            if (Objects.equals(continueDay,4)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_4()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_4())) / 10);
            }
            if (Objects.equals(continueDay,5)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_5()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_5())) / 10);
            }
            if (Objects.equals(continueDay,6)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_6()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_6())) / 10);
            }
            if (Objects.equals(continueDay,7)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_7()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_7())) / 10);
            }
            if (Objects.equals(continueDay,8)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_8()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_8())) / 10);
            }
            if (Objects.equals(continueDay,9)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_9()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_9())) / 10);
            }
            if (Objects.equals(continueDay,10)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_10()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_10())) / 10);
            }
            if (Objects.equals(continueDay,11)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_11()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_11())) / 10);
            }
            if (Objects.equals(continueDay,12)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_12()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_12())) / 10);
            }
            if (Objects.equals(continueDay,13)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_13()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_13())) / 10);
            }
            if (Objects.equals(continueDay,14)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_14()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_14())) / 10);
            }
            if (Objects.equals(continueDay,15)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_15()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold20_15())) / 10);
            }
        }
        if (Objects.equals(flag,"08")){
            if (Objects.equals(continueDay,1)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_1()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_1())) / 10);
            }
            if (Objects.equals(continueDay,2)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_2()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_2())) / 10);
            }
            if (Objects.equals(continueDay,3)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_3()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_3())) / 10);
            }
            if (Objects.equals(continueDay,4)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_4()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_4())) / 10);
            }
            if (Objects.equals(continueDay,5)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_5()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_5())) / 10);
            }
            if (Objects.equals(continueDay,6)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_6()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_6())) / 10);
            }
            if (Objects.equals(continueDay,7)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_7()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_7())) / 10);
            }
            if (Objects.equals(continueDay,8)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_8()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_8())) / 10);
            }
            if (Objects.equals(continueDay,9)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_9()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_9())) / 10);
            }
            if (Objects.equals(continueDay,10)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_10()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_10())) / 10);
            }
            if (Objects.equals(continueDay,11)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_11()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_11())) / 10);
            }
            if (Objects.equals(continueDay,12)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_12()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_12())) / 10);
            }
            if (Objects.equals(continueDay,13)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_13()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_13())) / 10);
            }
            if (Objects.equals(continueDay,14)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_14()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_14())) / 10);
            }
            if (Objects.equals(continueDay,15)){
                return NumUtil.save2Point(Objects.isNull(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_15()) ? 999999d : Double.parseDouble(String.valueOf(extremeInfoMaps.get(stationNo).get(0).getRainThreshold08_15())) / 10);
            }
        }


        return new Double(0);
    }

}
